/*
 * DIM-SUM操作系统 - 内存访问失败处理
 *
 * Copyright (C) 2023 国科础石(重庆)软件有限公司
 *
 * 作者: Dong Peng <w-pengdong@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#ifndef __ASM_MEMFAULT_H
#define __ASM_MEMFAULT_H
#include <asm/exception.h>
#include <asm/cpu_esr.h>

static inline bool is_write_abort(unsigned long esr)
{
	unsigned long cause = SCAUSE_TO_ECODE(esr);
	if (cause == EXC_STORE_ACCESS || cause == EXC_STORE_PAGE_FAULT)
		return true;
	return false;
}

static inline bool is_read_abort(unsigned long esr)
{
	unsigned long cause = SCAUSE_TO_ECODE(esr);
	if (cause == EXC_INST_MISALIGNED ||
	 cause == EXC_INST_ACCESS || cause == EXC_LOAD_ACCESS ||
	 cause == EXC_INST_PAGE_FAULT || cause == EXC_LOAD_PAGE_FAULT)
		return true;
	return false;
}

typedef int (*mem_fault_func)(struct exception_spot *s, u64 fault_addr, unsigned long esr);
int mem_fault_unknown(struct exception_spot *s, u64 fault_addr, unsigned long esr);
int mem_fault_translation(struct exception_spot *s, u64 fault_addr, unsigned long esr);
int mem_fault_inst_misaligned(struct exception_spot *s, u64 fault_addr, unsigned long esr);
int mem_fault_inst_access(struct exception_spot *s, u64 fault_addr, unsigned long esr);
int mem_fault_load_access(struct exception_spot *s, u64 fault_addr, unsigned long esr);
int mem_fault_store_access(struct exception_spot *s, u64 fault_addr, unsigned long esr);
int mem_fault_inst_page(struct exception_spot *s, u64 fault_addr, unsigned long esr);
int mem_fault_load_page(struct exception_spot *s, u64 fault_addr, unsigned long esr);
int mem_fault_store_page(struct exception_spot *s, u64 fault_addr, unsigned long esr);
int mem_fault_access(struct exception_spot *s, u64 fault_addr, unsigned long esr);
int mem_fault(struct exception_spot *s, u64 fault_addr, unsigned long esr);
int user_vmem_fault(struct exception_spot *s, u64 fault_addr, unsigned long esr);
int kernel_mode_fault(struct exception_spot *s, u64 fault_addr, unsigned long esr);
#endif /* __ASM_MEMFAULT_H */
